package com.chao.gulimall.ssoclient.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;

@Controller
public class HelloController {

    @Value("${sso.server.url}")
    private String ssoServerUrl;

    @Value("${sso.server.host}")
    private String ssoHost;

    @Value("${server.port}")
    private String port;
    @Value("${sso.server.checkUrl}")
    private String checkUrl;

    @Autowired
    RestTemplate restTemplate;

    /**
     * 无需登录就可以反应
     * @return
     */
    @ResponseBody
    @GetMapping("/hello")
    public String Hello(){
        return "hello";
    }

    /**
     * 需要能感知 这次实在 ssoserver登录成功后跳转回来的
     * token 如果不为空就可以理解为登录过  ，后续需要去sso服务器校验
     * @param model
     * @param session
     * @return
     */
//    @ResponseBody//跳转页面不能要  否则返回的是 字符串 list
//    @GetMapping("emps")//注意没有斜杠  无法跳转  总是报404
    @GetMapping("/emps")
    public String employees(Model model,HttpSession session,
                            @RequestParam(value = "token",required = false) String token){

        //TODO 这些逻辑是统一的，可以统一提取到filter中（开始）

        //token不为空 认为可能登录过
        //注意这里是从 ssoserver 返回时（不止第一次）校验【token】【关键】  设置 session
        //即 url中携带 token就对当前会话 设置 session（注意这里client1和client2会有两个会话，
        // 但是在浏览器中ssoserver留下了sso_token记号，起到了中间桥梁的作用）
        if(!StringUtils.isEmpty(token)){

            //TODO 去ssoserver中去获取真正的用户 账户信息
            RestTemplate restTemplate = new RestTemplate();//也可以容器汇总获取  配置
            ResponseEntity<String> entity = restTemplate.getForEntity("http://sso.com:8080/userInfo?token=" + token, String.class);
            String body = entity.getBody();//body是返回值  除此之外还有状态码的其他信息可以在头等地方获取
            //设置session
            session.setAttribute("loginUser",body);
            //这里session.setAttribute 的原理应该是将


//            //服务器校验
////            restTemplate.getForObject(checkUrl+"/{token}","可以封装一个对象",token);
////getForObject()其实比getForEntity()多包含了将HTTP转成POJO的功能，但是getForObject没有处理response的能力。因为它拿到手的就是成型的pojo。省略了很多response的信息。
//            String checkRes = restTemplate.getForObject(checkUrl + "/{token}", String.class, token);
//            if(!StringUtils.isEmpty(checkRes) && "ok".equalsIgnoreCase(checkRes)){
//
//                session.setAttribute("loginUser",body);
////                session.setAttribute("loginUser",token);
//                //这里session.setAttribute 的原理应该是将
//
//            }

        }

        Object loginUser = session.getAttribute("loginUser");
//        System.out.println(loginUser.toString());//取出来了 正是 redis中存的token 74348c4f06da44c0b55fa1e79d4b836d
        if(loginUser == null){
            //没登录,跳转到服务器登录
            return "redirect:"+ssoServerUrl+"?redirect_url=http://"+ssoHost+":"+port+"/emps";//这里的路径应该反射获取

            //TODO 这些逻辑是统一的，可以统一提取到filter中（结束）
        }else {
            ArrayList<String> emps = new ArrayList<>();
            emps.add("张三");
            emps.add("李四");
            model.addAttribute("emps",emps);
        }

        return "list";

//        <!--<ul>
//        [[$  |(|emp|)]] 错误写法  竖杠去掉看  注释的也会编译  thymeleaf   因为注释$符取东西也会报错
//                <li th:each="emp:${emps}">[[$|(|emp|)]]</li>&ndash;&gt;
//    </ul>-->
    }



}
